package com.itcoon.cloud.framework.springdoc.enums;/**
 * @author Athric Yu
 * 2025/1/20
 **/

import com.github.xiaoymin.knife4j.core.util.Assert;
import io.swagger.v3.oas.models.security.OAuthFlow;
import io.swagger.v3.oas.models.security.OAuthFlows;
import io.swagger.v3.oas.models.security.Scopes;
import io.swagger.v3.oas.models.security.SecurityScheme;

import java.util.Arrays;
import java.util.Map;

/**
 * @author Athric Yu
 * 2025/1/20
 **/

public enum SecuritySchemeEnum {

    BASIC_AUTH("Basic Auth", new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("basic")),
    BEARER_TOKEN("Bearer Token", new SecurityScheme().type(SecurityScheme.Type.HTTP).scheme("bearer")),
    OAUTH2_AUTHORIZATION_CODE("OAuth2 Authorization Code", new SecurityScheme().type(SecurityScheme.Type.OAUTH2).flows(new OAuthFlows().authorizationCode(new OAuthFlow()))),
    OAUTH2_CLIENT_CREDENTIALS("OAuth2 Client Credentials", new SecurityScheme().type(SecurityScheme.Type.OAUTH2).flows(new OAuthFlows().clientCredentials(new OAuthFlow()))),
    PASSWORD("Password", new SecurityScheme().type(SecurityScheme.Type.OAUTH2).flows(new OAuthFlows().password(new OAuthFlow()))),
    IMPLICIT("Implicit", new SecurityScheme().type(SecurityScheme.Type.OAUTH2).flows(new OAuthFlows().implicit(new OAuthFlow()))),
    OPENID_CONNECT("Openid Connect", new SecurityScheme().type(SecurityScheme.Type.OPENIDCONNECT));


    private final String name;
    private final SecurityScheme scheme;

    SecuritySchemeEnum(String name, SecurityScheme scheme) {
        this.name = name;
        this.scheme = scheme;
    }

    public String getName() {
        return name;
    }

    public SecurityScheme getScheme(String authorizationUrl, String tokenUrl, String oidcUrl, Map<String, String> scopesMap) {
        if (Arrays.asList(SecuritySchemeEnum.BASIC_AUTH, SecuritySchemeEnum.BEARER_TOKEN).contains(this)) {
            return scheme;
        } else if (this == SecuritySchemeEnum.OPENID_CONNECT) {
            Assert.notBlank(oidcUrl, "oidcUrl is required, it define with property 'itcoon.web.springdoc.oidc-url'");
            scheme.openIdConnectUrl(oidcUrl);
            return scheme;
        }
        OAuthFlow oauthFlow = null;
        if (this == SecuritySchemeEnum.OAUTH2_AUTHORIZATION_CODE) {
            oauthFlow = scheme.getFlows().getAuthorizationCode();
        } else if (this == SecuritySchemeEnum.PASSWORD) {
            oauthFlow = scheme.getFlows().getPassword();
        }else if(this == SecuritySchemeEnum.IMPLICIT){
            oauthFlow = scheme.getFlows().getImplicit();
        }else if(this == SecuritySchemeEnum.OAUTH2_CLIENT_CREDENTIALS){
            oauthFlow = scheme.getFlows().getClientCredentials();
        }
        Assert.notBlank(authorizationUrl, "authorizationUrl is required, it define with property 'itcoon.web.springdoc.authorization-url'");
        Assert.notBlank(tokenUrl, "tokenUrl is required, it define with property 'itcoon.web.springdoc.token-url'");
        Assert.notNull(scopesMap, "scopesMap is required, it define with property 'itcoon.web.springdoc.scopes-map'");
        Scopes scopes = new Scopes();
        for (Map.Entry<String, String> entry : scopesMap.entrySet()) {
            scopes.addString(entry.getKey(), entry.getValue());
        }
        oauthFlow.authorizationUrl(authorizationUrl).tokenUrl(tokenUrl).scopes(scopes);
        return scheme;
    }


}
